home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 4 / MacMania 4.toast / / Demo's / Igor Demo Pro / 1 PutContentsIn Igor Pro Folder / WaveMetrics Procedures / Utilities / Cross Hair Cursors next >
Text File  |  1996-04-03  |  13KB  |  476 lines

  1. #pragma rtGlobals= 1
  2. #include <Keyword-Value>
  3.  
  4. //    Cross hair Cursor package for IPro 3.0.1
  5. //    Documentation is in the Cross Hair Cursor Demo example experiment
  6. //    Version 1.0
  7. //    Filename: Cross Hair Cursors
  8.  
  9.  
  10.  
  11.  
  12. Macro HairlineCursor()
  13.     DoWindow/F HairlineCursorPanel
  14.     if( V_Flag )
  15.         return
  16.     endif
  17.     
  18.     NewDataFolder/O root:WinGlobals
  19.     NewDataFolder/O root:WinGlobals:HairlineCursorPanel
  20.     Variable/G root:WinGlobals:HairlineCursorPanel:curXtra=2
  21.     String/G root:WinGlobals:HairlineCursorPanel:csrgraph0="<no value>"
  22.     String/G root:WinGlobals:HairlineCursorPanel:csrgraph1="<no value>"
  23.     String/G root:WinGlobals:HairlineCursorPanel:csrgraphn="<no value>"
  24.     String/G root:WinGlobals:HairlineCursorPanel:expression="X1-X0"
  25.     HairlineCursorPanel()
  26. end
  27.  
  28.  
  29. | returns offset of given wave (assumed to be in top graph)
  30. | xoffset is real part, yoffset is imaginary part
  31. Function/C GetWaveOffset(w)
  32.     Wave w
  33.     
  34.     String s= TraceInfo("",NameOfWave (w),0)
  35.     if( strlen(s) == 0 )
  36.         return NaN
  37.     endif
  38.     String subs= "offset(x)={"
  39.     Variable v1= StrSearch(s,subs,0)
  40.     if( v1 == -1 )
  41.         return NaN
  42.     endif
  43.     v1 += strlen(subs)
  44.     Variable xoff= str2num(s[v1,1e6])
  45.     v1= StrSearch(s,",",v1)
  46.     Variable yoff= str2num(s[v1+1,1e6])
  47.     return cmplx(xoff,yoff)
  48. end
  49.  
  50.  
  51. Function AddHairCursor(n)
  52.     Variable n
  53.     
  54.     String dfSav= GetDataFolder(1)
  55.     String wname= WinName(0, 1)
  56.     
  57.     if( strlen(wname) == 0 )
  58.         Abort "no target graph"
  59.     endif
  60.     
  61.     NewDataFolder/O/S root:WinGlobals:$wname
  62.     
  63.     String/G root:WinGlobals:HairlineCursorPanel:$"csrgraph"+num2istr(n)= wname
  64.     
  65.     Variable xm=0,ym=0
  66.     
  67.     String yw= "HairY"+num2istr(n),xw= "HairX"+num2istr(n)
  68.     Make/O $yw={0,0,0,NaN,Inf,0,-Inf}
  69.     Make/O $xw={-Inf,0,Inf,NaN,0,0,0}
  70.     CheckDisplayed $yw
  71.     Variable notup= V_Flag == 0
  72.     if( notup )
  73.         AppendToGraph $yw vs $xw
  74.         ModifyGraph quickdrag($yw)=1,live($yw)=1
  75.         if( n==0 )
  76.             ModifyGraph rgb($yw)=(0,0,65534)    // blue
  77.         endif
  78.         if( n==1 )
  79.             ModifyGraph rgb($yw)=(0,65534,0)    // green
  80.         endif
  81.         if( n>1 )
  82.             ModifyGraph rgb($yw)=(0,0,0)        // black
  83.         endif
  84.     else
  85.         Variable/C xy= GetWaveOffset($yw)
  86.         xm= real(xy)
  87.         ym= imag(xy)
  88.     endif
  89.  
  90.     Variable x0,x1,y0,y1
  91.     GetAxis/Q left; y0= V_min; y1= V_max
  92.     GetAxis/Q bottom; x0= V_min; x1= V_max
  93.     if( notup %| (xm < min(x0,x1)) %| (xm > max(x0,x1)) )
  94.         xm= x0+(x1-x0)*(1+min(n,4))/5
  95.     endif
  96.     if( notup %| (ym < min(y0,y1)) %| (ym > max(y0,y1)) )
  97.         ym= y0+(y1-y0)*(1+min(n,4))/5
  98.     endif
  99.     
  100.  
  101.     ModifyGraph offset($yw)={xm,ym}
  102.     
  103.     Variable/G $"X"+num2istr(n)= xm
  104.     Variable/G $"Y"+num2istr(n)= ym
  105.     CreateUpdateZ("",n)
  106.  
  107.     String/G S_TraceOffsetInfo
  108.     Variable/G hairTrigger
  109.     SetFormula hairTrigger,"UpdateHairGlobals(S_TraceOffsetInfo)"
  110.     
  111.     SetDataFolder dfSav
  112. end
  113.  
  114. Function UpdateHairGlobals(tinfo)
  115.     String tinfo
  116.     
  117.     tinfo= ";"+tinfo
  118.     
  119.     String s= ";GRAPH:"
  120.     Variable p0= StrSearch(tinfo,s,0),p1
  121.     if( p0 < 0 )
  122.         return 0
  123.     endif
  124.     p0 += strlen(s)
  125.     p1= StrSearch(tinfo,";",p0)
  126.     String gname= tinfo[p0,p1-1]
  127.     String thedf= "root:WinGlobals:"+gname
  128.     if( !DataFolderExists(thedf) )
  129.         return 0
  130.     endif
  131.     
  132.     s= ";TNAME:HairY"
  133.     p0= StrSearch(tinfo,s,0)
  134.     if( p0 < 0 )
  135.         return 0
  136.     endif
  137.     p0 += strlen(s)
  138.     p1= StrSearch(tinfo,";",p0)
  139.     Variable n= str2num(tinfo[p0,p1-1])
  140.     
  141.     String dfSav= GetDataFolder(1)
  142.     SetDataFolder thedf
  143.     
  144.     s= "XOFFSET:"
  145.     p0=  StrSearch(tinfo,s,0)
  146.     if( p0 >= 0 )
  147.         p0 += strlen(s)
  148.         p1= StrSearch(tinfo,";",p0)
  149.         Variable/G $"X"+num2str(n)=str2num(tinfo[p0,p1-1])
  150.     endif
  151.     
  152.     s= "YOFFSET:"
  153.     p0=  StrSearch(tinfo,s,0)
  154.     if( p0 >= 0 )
  155.         p0 += strlen(s)
  156.         p1= StrSearch(tinfo,";",p0)
  157.         Variable/G $"Y"+num2str(n)=str2num(tinfo[p0,p1-1])
  158.     endif
  159.     
  160.     CreateUpdateZ(gname,n)
  161.     
  162.     SetDataFolder dfSav
  163. end
  164.  
  165. // this is intended to be called with DF set to loc of globals
  166. Function CreateUpdateZ(gname,n)
  167.     String gname                    // the graph name (empty or cur graph)
  168.     Variable n
  169.     
  170.     NVAR gXn= $"X"+num2str(n)
  171.     NVAR gYn= $"Y"+num2str(n)
  172.     
  173.     
  174.     Variable Xn=gXn,Yn=gYn,Xp,Yp
  175.     
  176.     String iname= ImageNameList(gname, ";")
  177.     Variable p1= StrSearch(iname,";",0)
  178.     if( p1 > 1 )
  179.         iname= iname[0,p1-1]
  180.         Wave w= ImageNameToWaveRef(gname, iname)
  181.         if( WaveExists(w) )
  182.             String info= ";"+ImageInfo(gname, iname, 0)
  183.             Wave xw= $GetWavePathFromImageInfo("X",info)
  184.             Wave yw= $GetWavePathFromImageInfo("Y",info)
  185.             if( WaveExists(xw) )
  186.                 Xp= BinarySearchInterp(xw,Xn)
  187.                 Xn= pnt2x(w, Xp)
  188.             endif
  189.             if( WaveExists(yw) )
  190.                 Yp= BinarySearchInterp(yw,Yn)
  191.                 Yn= DimOffset(w, 1) + Yp *DimDelta(w,1)
  192.             endif
  193.             Variable/G $"Z"+num2str(n)= w(Xn)(Yn)
  194.         endif
  195.     endif
  196. end    
  197.  
  198. Function/S GetWavePathFromImageInfo(pre,info)
  199.     String pre,info
  200.     
  201.     String wname= StrByKey(";"+pre+"WAVE",info)
  202.     String wpath= StrByKey(";"+pre+"WAVEDF",info)
  203.     
  204.     return wpath+PossiblyQuoteName(wname)
  205. end
  206.  
  207. Function UpdateCursorReadout(n)
  208.     Variable n
  209.  
  210.     String df= "root:WinGlobals:"+WinName(0, 1)+":"
  211.     String suf= num2str(n)
  212.     if( n>1 )
  213.         suf= "n"
  214.     endif
  215.     String xval= df+"X"+num2str(n)
  216.     if( Exists(xval) != 2 )
  217.         xval= "#\"no value\""
  218.     endif
  219.     String yval= df+"Y"+num2str(n)
  220.     if( Exists(yval) != 2 )
  221.         yval= "#\"no value\""
  222.     endif
  223.     String zval= df+"Z"+num2str(n)
  224.     if( Exists(zval) != 2 )
  225.         zval= "#\"no value\""
  226.     endif
  227.     
  228.     Execute "ValDisplay valdispX"+suf+",value="+xval
  229.     Execute "ValDisplay valdispY"+suf+",value="+yval
  230.     Execute "ValDisplay valdispZ"+suf+",value="+zval
  231.     
  232.     if( n>=2 )
  233.         String/G root:WinGlobals:HairlineCursorPanel:csrgraphn="<no value>"
  234.         SetFormula root:WinGlobals:HairlineCursorPanel:csrgraphn,"csrgraph"+num2str(n)
  235.     endif
  236. end
  237.  
  238. Function UpdateCursorDeltas()
  239.     String dimletter= "XYZ"
  240.     Variable i=0
  241.     do
  242.         String basename= "valdisp"+dimletter[i]
  243.         ControlInfo $basename+"0"
  244.         Variable x0valid= V_Flag==4
  245.         String x0expr= "not valid"
  246.         if( x0valid )
  247.             x0expr= S_value
  248.         endif
  249.     
  250.         ControlInfo $basename+"1"
  251.         Variable x1valid= V_Flag==4
  252.         String x1expr= "not valid"
  253.         if( x1valid )
  254.             x1expr= S_value
  255.         endif
  256.         
  257.         String dxexpr= "#\"no value\""
  258.         if( x0valid %& x1valid )
  259.             dxexpr= x1expr+"-"+x0expr
  260.         endif
  261.         Execute "ValDisplay "+basename+"D ,value="+ dxexpr
  262.         
  263.         i+=1
  264.     while(i<=2 )
  265.     
  266. end
  267.  
  268.  
  269.  
  270. Function ButtonProcSetn(ctrlName) : ButtonControl
  271.     String ctrlName
  272.     
  273.     if( CmpStr(ctrlName,"Set0") == 0 )
  274.         AddHairCursor(0)
  275.         UpdateCursorReadout(0)
  276.         UpdateCursorDeltas()
  277.     endif
  278.     if( CmpStr(ctrlName,"Set1") == 0 )
  279.         AddHairCursor(1)
  280.         UpdateCursorReadout(1)
  281.         UpdateCursorDeltas()
  282.     endif
  283.     if( CmpStr(ctrlName,"Set2") == 0 )
  284.         NVAR curXtra= root:WinGlobals:HairlineCursorPanel:curXtra
  285.         AddHairCursor(curXtra)
  286.         UpdateCursorReadout(curXtra)
  287.     endif
  288. End
  289.  
  290. Function ButtonProcRemoven(ctrlName) : ButtonControl
  291.     String ctrlName
  292.     
  293.     Variable n= -1
  294.     if( CmpStr(ctrlName,"Remove0") == 0 )
  295.         n=0
  296.     endif
  297.     if( CmpStr(ctrlName,"Remove1") == 0 )
  298.         n=1
  299.     endif
  300.     if( CmpStr(ctrlName,"Remove2") == 0 )
  301.         n=NumVarOrDefault("root:WinGlobals:HairlineCursorPanel:curXtra",2)
  302.     endif
  303.  
  304.     CheckDisplayed TraceNameToWaveRef("", "HairY"+num2istr(n))
  305.     if( V_Flag != 0 )
  306.         RemoveFromGraph $"HairY"+num2istr(n)
  307.     endif
  308. End
  309.  
  310. Window HairlineCursorPanel() : Panel
  311.     PauseUpdate; Silent 1        | building window...
  312.     NewPanel /W=(329,44,777,184)
  313.     SetDrawLayer UserBack
  314.     SetDrawEnv fname= "Geneva"
  315.     DrawText 13,18,"Cursor:"
  316.     SetDrawEnv fstyle= 1,textrgb= (0,0,65535)
  317.     DrawText 29,42,"0"
  318.     SetDrawEnv fname= "Geneva",fstyle= 1,textrgb= (3,52428,1)
  319.     DrawText 29,63,"1"
  320.     SetDrawEnv fname= "Geneva"
  321.     DrawText 146,18,"X"
  322.     DrawLine 17,17,436,17
  323.     SetDrawEnv fname= "Geneva"
  324.     DrawText 229,18,"Y"
  325.     SetDrawEnv fname= "Geneva"
  326.     DrawText 320,18,"Z"
  327.     SetDrawEnv fname= "Geneva",fsize= 9,textxjust= 2,textyjust= 1
  328.     DrawText 107,97,"delta (1-0):"
  329.     SetDrawEnv fname= "Geneva"
  330.     DrawText 379,17,"Graph"
  331.     Button Set0,pos={45,25},size={29,17},proc=ButtonProcSetn,title="Set"
  332.     Button Set1,pos={45,45},size={29,17},proc=ButtonProcSetn,title="Set"
  333.     Button Set2,pos={45,65},size={29,17},proc=ButtonProcSetn,title="Set"
  334.     Button Remove0,pos={78,25},size={29,17},proc=ButtonProcRemoven,title="Rm"
  335.     Button Remove1,pos={78,45},size={29,17},proc=ButtonProcRemoven,title="Rm"
  336.     Button Remove2,pos={78,65},size={29,17},proc=ButtonProcRemoven,title="Rm"
  337.     ValDisplay valdispX0,pos={115,27},size={77,12},fSize=9
  338.     ValDisplay valdispX0,limits={0,0,0},barmisc={0,1000},value= #"no value"
  339.     ValDisplay valdispY0,pos={198,27},size={77,12},fSize=9
  340.     ValDisplay valdispY0,limits={0,0,0},barmisc={0,1000},value= #"no value"
  341.     ValDisplay valdispZ0,pos={281,27},size={76,12},fSize=9
  342.     ValDisplay valdispZ0,limits={0,0,0},barmisc={0,1000},value= #"no value"
  343.     ValDisplay valdispX1,pos={115,48},size={77,12},fSize=9
  344.     ValDisplay valdispX1,limits={0,0,0},barmisc={0,1000},value= #"no value"
  345.     ValDisplay valdispY1,pos={198,48},size={77,12},fSize=9
  346.     ValDisplay valdispY1,limits={0,0,0},barmisc={0,1000},value= #"no value"
  347.     ValDisplay valdispZ1,pos={281,48},size={77,12},fSize=9
  348.     ValDisplay valdispZ1,limits={0,0,0},barmisc={0,1000},value= #"no value"
  349.     ValDisplay valdispXn,pos={115,68},size={77,12},fSize=9
  350.     ValDisplay valdispXn,limits={0,0,0},barmisc={0,1000},value= #"no value"
  351.     ValDisplay valdispYn,pos={198,68},size={77,12},fSize=9
  352.     ValDisplay valdispYn,limits={0,0,0},barmisc={0,1000},value= #"no value"
  353.     ValDisplay valdispZn,pos={281,68},size={77,12},fSize=9
  354.     ValDisplay valdispZn,limits={0,0,0},barmisc={0,1000},value= #"no value"
  355.     SetVariable setvar0,pos={8,66},size={34,15},proc=SetVarProcChangeCurXtra,title=" "
  356.     SetVariable setvar0,limits={2,5,1},value= root:WinGlobals:HairlineCursorPanel:curXtra
  357.     ValDisplay valdispXD,pos={115,91},size={77,12},fSize=9
  358.     ValDisplay valdispXD,limits={0,0,0},barmisc={0,1000},value= #"no value"
  359.     ValDisplay valdispYD,pos={198,90},size={77,12},fSize=9
  360.     ValDisplay valdispYD,limits={0,0,0},barmisc={0,1000},value= #"no value"
  361.     ValDisplay valdispZD,pos={281,90},size={77,12},fSize=9
  362.     ValDisplay valdispZD,limits={0,0,0},barmisc={0,1000},value= #"no value"
  363.     SetVariable setvarGrf0,pos={362,27},size={76,12},title=" ",fSize=9
  364.     SetVariable setvarGrf0,limits={-INF,INF,1},value= root:WinGlobals:HairlineCursorPanel:csrgraph0
  365.     SetVariable setvarGrf1,pos={362,48},size={76,12},title=" ",fSize=9
  366.     SetVariable setvarGrf1,limits={-INF,INF,1},value= root:WinGlobals:HairlineCursorPanel:csrgraph1
  367.     SetVariable setvarGrf2,pos={362,67},size={76,12},title=" ",fSize=9
  368.     SetVariable setvarGrf2,limits={-INF,INF,1},value= root:WinGlobals:HairlineCursorPanel:csrgraphn
  369.     SetVariable setvarExpression,pos={115,118},size={190,15},title=" "
  370.     SetVariable setvarExpression,limits={-INF,INF,1},value= root:WinGlobals:HairlineCursorPanel:expression
  371.     Button buttonPrint,pos={58,115},size={50,20},proc=ButtonProcPrintExpr,title="Print:"
  372. EndMacro
  373.  
  374. // used during development
  375. xMacro NoValueize()
  376.     ValDisplay valdispX0,value= #"no value"
  377.     ValDisplay valdispY0,value= #"no value"
  378.     ValDisplay valdispZ0,value= #"no value"
  379.     ValDisplay valdispX1,value= #"no value"
  380.     ValDisplay valdispY1,value= #"no value"
  381.     ValDisplay valdispZ1,value= #"no value"
  382.     ValDisplay valdispXn,value= #"no value"
  383.     ValDisplay valdispYn,value= #"no value"
  384.     ValDisplay valdispZn,value= #"no value"
  385.     ValDisplay valdispXD,value= #"no value"
  386.     ValDisplay valdispYD,value= #"no value"
  387.     ValDisplay valdispZD,value= #"no value"
  388. end
  389.  
  390. Function SetVarProcChangeCurXtra(ctrlName,varNum,varStr,varName) : SetVariableControl
  391.     String ctrlName
  392.     Variable varNum
  393.     String varStr
  394.     String varName
  395.  
  396.     UpdateCursorReadout(varNum)
  397. End
  398.  
  399. Function ButtonProcPrintExpr(ctrlName) : ButtonControl
  400.     String ctrlName
  401.  
  402.     SVAR expr= root:WinGlobals:HairlineCursorPanel:expression
  403.     String s= TranslateXYZExpr(expr)
  404.     Print  "•print "+s
  405.     Execute "print "+s
  406. End
  407.  
  408. Function/S TranslateXYZExpr(expr)
  409.     String expr
  410.     
  411.     variable p0,p1,p2
  412.     
  413.     //
  414.     //    First we search for patterns like X<digit>, Y<digit> and Z<digit>
  415.     //    If found, we insert a single quite in front to identify the location of the
  416.     //    pattern. This whole thing would be much easier if we had a grep style
  417.     //    pattern search. Even if we just had a case insensitive search, all the p1 vs p2
  418.     //    stuff would dissapear.
  419.     //
  420.     String s1="XYZ"
  421.     Variable i=0
  422.     do
  423.         String ch= s1[i]        // the char to search for
  424.         p0=0
  425.         do
  426.             p1= StrSearch(expr,ch,p0)                    // upper case search
  427.             p2= StrSearch(expr,LowerStr(ch),p0)        // lower case search
  428.             if( (p1 < 0) %& (p2 < 0) )                    // didn't find either
  429.                 break
  430.             endif
  431.             if( (p1>=0) %& (p2>=0) )                    // found both
  432.                 p1= min(p1,p2)                        // take the first one
  433.             else
  434.                 p1= max(p1,p2)                        // just one, the other is -1
  435.             endif
  436.             if( (char2num(expr[p1+1]) >= 0x30) %& (char2num(expr[p1+1]) <= 0x39) ) // digit?
  437.                 expr[p1]= "'"
  438.                 p0= p1+3
  439.             else
  440.                 p0= p1+2
  441.             endif
  442.         while(1)
  443.         i+=1
  444.     while(i<3)
  445.     
  446.     //
  447.     //    Now, for each singe quote, we extract the digit, use that to look up the
  448.     //    name of the graph (if any) and then replace the single quote with the path
  449.     //    to the variable. We verify the variable exists and return an error string
  450.     //    if not
  451.     //
  452.     p0= 0
  453.     do
  454.         p1= StrSearch(expr,"'",p0)
  455.         if( p1<0 )
  456.             break
  457.         endif
  458.         Variable n= char2num(expr[p1+2])-0x30
  459.         String gnstr= "root:WinGlobals:HairlineCursorPanel:csrgraph"+num2str(n)
  460.         SVAR gname= $gnstr
  461.         if( Exists(gnstr) != 2 )
  462.             expr= "\"ERROR: specified cursor set does not exist ("+gnstr+")\""
  463.             break
  464.         endif
  465.         String vpath=  "root:WinGlobals:"+gname+":"+expr[p1+1,p1+2]
  466.         if( Exists(vpath) != 2 )
  467.             expr= "\"ERROR: specified cursor does not exist ("+vpath+")\""
  468.             break
  469.         endif
  470.         expr[p1,p1+2]= vpath
  471.         p0= p1+strlen(vpath)
  472.     while(1)
  473.     
  474.     return expr
  475. end
  476.